package com.common.event.listener;


import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.common.event.EventAnnotation;
import com.common.event.EventMessage;
import com.common.event.tuple.TwoTuple;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;

/**
 * 
* @Title: EventMessageListenerRouter.java 
* @Package com.common.event.listener
* @Description: 事件监听具体路由器
* @author tangzhibin
* @date 2017年2月28日 
* @version V1.0
 */
public class EventMessageListenerRouter{
	

	public static final Logger	LOGGER	= LoggerFactory.getLogger(EventMessageListenerRouter.class);
	

	private List<EventMessageListener>	eventListeners;
	
	public EventMessageListenerRouter(){
	}
	
	public EventMessageListenerRouter(List<EventMessageListener>	eventListeners){
		this.eventListeners=eventListeners;
	}
	
	public List<EventMessageListener> getEventListeners() {
		return eventListeners;
	}
	
	public void setEventListeners(List<EventMessageListener> eventListeners) {
		this.eventListeners = eventListeners;
	}
	
	private EventMessageListener getEventExecutor(String eventKey){
		for(EventMessageListener lis:eventListeners){
			EventAnnotation eventAnnotation = lis.getClass().getAnnotation(EventAnnotation.class);
			if(eventAnnotation!=null && StringUtils.equalsIgnoreCase(eventAnnotation.evnetKey(), eventKey)  ){
				return lis;
			}
		}
		throw new IllegalArgumentException("Illegal eventKey:"+eventKey);
	}
	
	/**
	 * 事件路由模板方法
	 * @param eventMessage
	 * @param eventKey
	 * @return
	 */
	@Subscribe
	@AllowConcurrentEvents
	public boolean doEventMessage(EventMessage eventMessage) {
		EventMessageListener eventExecutor=getEventExecutor(eventMessage.getEventKey());
		TwoTuple<Boolean,?> doResult=null;
		try {
			doResult=eventExecutor.doEvent(eventMessage);
		} catch (Exception e) {
			LOGGER.error(eventMessage.getEventKey()+" doEventMessage error", e);
		}finally{
			if(doResult!=null && eventExecutor!=null && doResult.getFirst()){
				try {
					return eventExecutor.doEventAfter(eventMessage,doResult.getSecond());
				} catch (Exception e2) {
					LOGGER.error(eventMessage.getEventKey()+" doEventAfter error", e2);
				}
			}
		}
		return false;
	}
	
	
}
